home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmcd-1.4 / libdi.d / os_hpux.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  6.2 KB  |  285 lines

  1. /*
  2.  *   libdi - CD Audio Player Device Interface Library
  3.  *
  4.  *   Copyright (C) 1995  Ti Kan
  5.  *   E-mail: ti@amb.org
  6.  *
  7.  *   This program is free software; you can redistribute it and/or modify
  8.  *   it under the terms of the GNU General Public License as published by
  9.  *   the Free Software Foundation; either version 2 of the License, or
  10.  *   (at your option) any later version.
  11.  *
  12.  *   This program is distributed in the hope that it will be useful,
  13.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *   GNU General Public License for more details.
  16.  *
  17.  *   You should have received a copy of the GNU General Public License
  18.  *   along with this program; if not, write to the Free Software
  19.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  *   This software module contains code that interfaces the CD player
  22.  *   application to the HP-UX Release 9.0 operating system.  The name
  23.  *   "HP" and "hpux" are used here for identification purposes only.
  24.  *   This software and its author are not affiliated with the Hewlett-
  25.  *   Packard Company.
  26.  */
  27. #ifndef LINT
  28. static char *_os_hpux_c_ident_ = "@(#)os_hpux.c    5.6 94/12/28";
  29. #endif
  30.  
  31. #include "common.d/appenv.h"
  32. #include "common.d/util.h"
  33. #include "libdi.d/libdi.h"
  34. #include "libdi.d/scsipt.h"
  35.  
  36. #if defined(__hpux) && defined(DI_SCSIPT) && !defined(DEMO_ONLY)
  37.  
  38. extern appdata_t    app_data;
  39. extern bool_t        scsipt_notrom_error;
  40. extern FILE        *errfp;
  41.  
  42. STATIC int        pthru_fd = -1;    /* Passthrough device file desc */
  43.  
  44.  
  45. /*
  46.  * pthru_send
  47.  *    Build SCSI CDB and send command to the device.
  48.  *
  49.  * Args:
  50.  *    opcode - SCSI command opcode
  51.  *    addr - The "address" portion of the SCSI CDB
  52.  *    buf - Pointer to data buffer
  53.  *    size - Number of bytes to transfer
  54.  *    rsvd - The "reserved" portion of the SCSI CDB
  55.  *    length - The "length" portion of the SCSI CDB
  56.  *    param - The "param" portion of the SCSI CDB
  57.  *    control - The "control" portion of the SCSI CDB
  58.  *    rw - Data transfer direction flag (READ_OP or WRITE_OP)
  59.  *    prnerr - Whether an error message should be displayed
  60.  *         when a command fails
  61.  *
  62.  * Return:
  63.  *    TRUE - command completed successfully
  64.  *    FALSE - command failed
  65.  */
  66. bool_t
  67. pthru_send(
  68.     byte_t        opcode,
  69.     word32_t    addr,
  70.     byte_t        *buf,
  71.     word32_t    size,
  72.     byte_t        rsvd,
  73.     word32_t    length,
  74.     byte_t        param,
  75.     byte_t        control,
  76.     byte_t        rw,
  77.     bool_t        prnerr
  78. )
  79. {
  80.     struct sctl_io    sctl;
  81.  
  82.     
  83.     if (pthru_fd < 0 || scsipt_notrom_error)
  84.         return FALSE;
  85.  
  86.     memset(&sctl, 0, sizeof(sctl));
  87.  
  88.     /* set up SCSI CDB */
  89.     switch (opcode & 0xf0) {
  90.     case 0xa0:
  91.     case 0xe0:
  92.         /* 12-byte commands */
  93.         sctl.cdb[0] = opcode;
  94.         sctl.cdb[1] = param;
  95.         sctl.cdb[2] = (addr >> 24) & 0xff;
  96.         sctl.cdb[3] = (addr >> 16) & 0xff;
  97.         sctl.cdb[4] = (addr >> 8) & 0xff;
  98.         sctl.cdb[5] = (addr & 0xff);
  99.         sctl.cdb[6] = (length >> 24) & 0xff;
  100.         sctl.cdb[7] = (length >> 16) & 0xff;
  101.         sctl.cdb[8] = (length >> 8) & 0xff;
  102.         sctl.cdb[9] = length & 0xff;
  103.         sctl.cdb[10] = rsvd;
  104.         sctl.cdb[11] = control;
  105.  
  106.         sctl.cdb_length = 12;
  107.         break;
  108.  
  109.     case 0xc0:
  110.     case 0xd0:
  111.     case 0x20:
  112.     case 0x30:
  113.     case 0x40:
  114.         /* 10-byte commands */
  115.         sctl.cdb[0] = opcode;
  116.         sctl.cdb[1] = param;
  117.         sctl.cdb[2] = (addr >> 24) & 0xff;
  118.         sctl.cdb[3] = (addr >> 16) & 0xff;
  119.         sctl.cdb[4] = (addr >> 8) & 0xff;
  120.         sctl.cdb[5] = addr & 0xff;
  121.         sctl.cdb[6] = rsvd;
  122.         sctl.cdb[7] = (length >> 8) & 0xff;
  123.         sctl.cdb[8] = length & 0xff;
  124.         sctl.cdb[9] = control;
  125.  
  126.         sctl.cdb_length = 10;
  127.         break;
  128.  
  129.     case 0x00:
  130.     case 0x10:
  131.         /* 6-byte commands */
  132.         sctl.cdb[0] = opcode;
  133.         sctl.cdb[1] = param;
  134.         sctl.cdb[2] = (addr >> 8) & 0xff;
  135.         sctl.cdb[3] = addr & 0xff;
  136.         sctl.cdb[4] = length & 0xff;
  137.         sctl.cdb[5] = control;
  138.  
  139.         sctl.cdb_length = 6;
  140.         break;
  141.  
  142.     default:
  143.         if (app_data.scsierr_msg && prnerr)
  144.             fprintf(errfp, "0x%02x: Unknown SCSI opcode\n",
  145.                 opcode);
  146.         return FALSE;
  147.     }
  148.  
  149.     DBGDUMP("SCSI CDB bytes", (byte_t *) sctl.cdb, sctl.cdb_length);
  150.  
  151.     /* set up sctl_io */
  152.     sctl.data = buf;
  153.     sctl.data_length = (unsigned) size;
  154.     if (rw == READ_OP && size > 0)
  155.         sctl.flags = SCTL_READ;
  156.     else
  157.         sctl.flags = 0;
  158.  
  159.     sctl.max_msecs = 10000;    /* Allow 10 seconds for command */
  160.  
  161.     /* Send the command down via the "pass-through" interface */
  162.     if (ioctl(pthru_fd, SIOC_IO, &sctl) < 0) {
  163.         if (app_data.scsierr_msg && prnerr)
  164.             perror("SIOC_IO ioctl failed");
  165.         return FALSE;
  166.     }
  167.  
  168.     if (sctl.cdb_status != S_GOOD) {
  169.         if (app_data.scsierr_msg && prnerr) {
  170.             fprintf(errfp,
  171.                 "CD audio: %s %s:\n%s=0x%x %s=0x%x %s=0x%x",
  172.                 "SCSI command fault on",
  173.                 app_data.device,
  174.                 "Opcode",
  175.                 opcode,
  176.                 "Cdb_status",
  177.                 sctl.cdb_status,
  178.                 "Sense_status",
  179.                 sctl.sense_status);
  180.  
  181.             if (sctl.sense_status == S_GOOD && sctl.sense_xfer > 2)
  182.                 fprintf(errfp,
  183.                     " Key=0x%x Code=0x%x Qual=0x%x\n",
  184.                     sctl.sense[2] & 0x0f,
  185.                     sctl.sense[12],
  186.                     sctl.sense[13]);
  187.             else
  188.                 fprintf(errfp, "\n");
  189.         }
  190.  
  191.         return FALSE;
  192.     }
  193.  
  194.     return TRUE;
  195. }
  196.  
  197.  
  198. /*
  199.  * pthru_open
  200.  *    Open SCSI pass-through device
  201.  *
  202.  * Args:
  203.  *    path - device path name string
  204.  *
  205.  * Return:
  206.  *    TRUE - open successful
  207.  *    FALSE - open failed
  208.  */
  209. bool_t
  210. pthru_open(char *path)
  211. {
  212.     struct stat    stbuf;
  213.     char        errstr[ERR_BUF_SZ];
  214.  
  215.     /* Check for validity of device node */
  216.     if (stat(path, &stbuf) < 0) {
  217.         sprintf(errstr, app_data.str_staterr, path);
  218.         cd_fatal_popup(app_data.str_fatal, errstr);
  219.         return FALSE;
  220.     }
  221.     if (!S_ISCHR(stbuf.st_mode)) {
  222.         sprintf(errstr, app_data.str_noderr, path);
  223.         cd_fatal_popup(app_data.str_fatal, errstr);
  224.         return FALSE;
  225.     }
  226.  
  227.     if ((pthru_fd = open(path, O_RDONLY)) < 0) {
  228.         DBGPRN(errfp, "Cannot open %s: errno=%d\n", path, errno);
  229.         return FALSE;
  230.     }
  231.  
  232.     /* Obtain exclusive open */
  233.     if (ioctl(pthru_fd, SIOC_EXCLUSIVE, 1) < 0) {
  234.         DBGPRN(errfp, "Cannot set SIOC_EXCLUSIVE: errno=%d\n", errno);
  235.         close(pthru_fd);
  236.         pthru_fd = -1;
  237.         return FALSE;
  238.     }
  239.  
  240.     return TRUE;
  241. }
  242.  
  243.  
  244. /*
  245.  * pthru_close
  246.  *    Close SCSI pass-through device
  247.  *
  248.  * Args:
  249.  *    Nothing.
  250.  *
  251.  * Return:
  252.  *    Nothing.
  253.  */
  254. void
  255. pthru_close(void)
  256. {
  257.     if (pthru_fd >= 0) {
  258.         /* Relinquish exclusive open */
  259.         ioctl(pthru_fd, SIOC_EXCLUSIVE, 0);
  260.  
  261.         close(pthru_fd);
  262.         pthru_fd = -1;
  263.     }
  264. }
  265.  
  266.  
  267. /*
  268.  * pthru_vers
  269.  *    Return OS Interface Module version string
  270.  *
  271.  * Args:
  272.  *    Nothing.
  273.  *
  274.  * Return:
  275.  *    Module version text string.
  276.  */
  277. char *
  278. pthru_vers(void)
  279. {
  280.     return ("OS Interface module (for HP-UX)\n");
  281. }
  282.  
  283. #endif    /* __hpux DI_SCSIPT DEMO_ONLY */
  284.  
  285.